package cn.jishiyu11.xeqb.utils.systemUtils

import android.annotation.SuppressLint
import android.content.Context
import android.telephony.TelephonyManager
import android.text.TextUtils

import java.lang.reflect.Method
import java.util.UUID

/**
 * Created by vvguoliang on 2017/7/26.
 * 获取双卡中的IMEI
 */

class CTelephoneInfo private constructor() {

    var imeiSIM1: String? = null
        private set// IMEI
    var imeiSIM2: String? = null
        private set//IMEI
    var iNumeric1: String? = null
        private set//sim1 code number
    var iNumeric2: String? = null
        private set//sim2 code number
    var isSIM1Ready: Boolean = false
        private set//sim1
    var isSIM2Ready: Boolean = false
        private set//sim2
    private var iDataConnected1: String? = "0"//sim1 0 no, 1 connecting, 2 connected, 3 suspended.
    private var iDataConnected2: String? = "0"//sim2

    var line1Number: String? = null
    var line2Number: String? = null

    val isDualSim: Boolean
        get() = imeiSIM2 != null

    val isDataConnected1: Boolean
        get() = TextUtils.equals(iDataConnected1, "2") || TextUtils.equals(iDataConnected1, "1")

    val isDataConnected2: Boolean
        get() = TextUtils.equals(iDataConnected2, "2") || TextUtils.equals(iDataConnected2, "1")

    val iNumeric: String?
        get() {
            if (imeiSIM2 != null) {
                if (iNumeric1 != null && iNumeric1!!.length > 1)
                    return iNumeric1

                if (iNumeric2 != null && iNumeric2!!.length > 1)
                    return iNumeric2
            }
            return iNumeric1
        }

    @SuppressLint("HardwareIds", "MissingPermission")
    fun setCTelephoneInfo() {
        val telephonyManager = mContext!!.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        CTelephoneInfo!!.imeiSIM1 = telephonyManager.deviceId
        CTelephoneInfo!!.imeiSIM2 = null
        this.line1Number = telephonyManager.line1Number
        try {
            CTelephoneInfo!!.imeiSIM1 = getOperatorBySlot(mContext!!, "getDeviceIdGemini", 0)
            CTelephoneInfo!!.imeiSIM2 = getOperatorBySlot(mContext!!, "getDeviceIdGemini", 1)
            CTelephoneInfo!!.iNumeric1 = getOperatorBySlot(mContext!!, "getSimOperatorGemini", 0)
            CTelephoneInfo!!.iNumeric2 = getOperatorBySlot(mContext!!, "getSimOperatorGemini", 1)
            CTelephoneInfo!!.iDataConnected1 = getOperatorBySlot(mContext!!, "getDataStateGemini", 0)
            CTelephoneInfo!!.iDataConnected2 = getOperatorBySlot(mContext!!, "getDataStateGemini", 1)
        } catch (e: GeminiMethodNotFoundException) {
            e.printStackTrace()
            try {
                CTelephoneInfo!!.imeiSIM1 = getOperatorBySlot(mContext!!, "getDeviceId", 0)
                CTelephoneInfo!!.imeiSIM2 = getOperatorBySlot(mContext!!, "getDeviceId", 1)
                CTelephoneInfo!!.iNumeric1 = getOperatorBySlot(mContext!!, "getSimOperator", 0)
                CTelephoneInfo!!.iNumeric2 = getOperatorBySlot(mContext!!, "getSimOperator", 1)
                CTelephoneInfo!!.iDataConnected1 = getOperatorBySlot(mContext!!, "getDataState", 0)
                CTelephoneInfo!!.iDataConnected2 = getOperatorBySlot(mContext!!, "getDataState", 1)
            } catch (e1: GeminiMethodNotFoundException) {
                //Call here for next manufacturer's predicted method name if you wish
                e1.printStackTrace()
            }

        }

        CTelephoneInfo!!.isSIM1Ready = telephonyManager.simState == TelephonyManager.SIM_STATE_READY
        CTelephoneInfo!!.isSIM2Ready = false

        try {
            CTelephoneInfo!!.isSIM1Ready = getSIMStateBySlot(mContext!!, "getSimStateGemini", 0)
            CTelephoneInfo!!.isSIM2Ready = getSIMStateBySlot(mContext!!, "getSimStateGemini", 1)
        } catch (e: GeminiMethodNotFoundException) {
            e.printStackTrace()
            try {
                CTelephoneInfo!!.isSIM1Ready = getSIMStateBySlot(mContext!!, "getSimState", 0)
                CTelephoneInfo!!.isSIM2Ready = getSIMStateBySlot(mContext!!, "getSimState", 1)
            } catch (e1: GeminiMethodNotFoundException) {
                //Call here for next manufacturer's predicted method name if you wish
                e1.printStackTrace()
            }

        }

    }

    private class GeminiMethodNotFoundException(info: String) : Exception(info) {
        companion object {
            /**
             *
             */
            private val serialVersionUID = -3241033488141442594L
        }
    }

    companion object {
        @SuppressLint("StaticFieldLeak")
        private var CTelephoneInfo: CTelephoneInfo? = null
        private var mContext: Context? = null

        @Synchronized
        fun getInstance(context: Context): CTelephoneInfo {
            if (CTelephoneInfo == null) {
                CTelephoneInfo = CTelephoneInfo()
            }
            mContext = context
            return CTelephoneInfo as CTelephoneInfo
        }

        @Throws(CTelephoneInfo.GeminiMethodNotFoundException::class)
        private fun getOperatorBySlot(context: Context, predictedMethodName: String, slotID: Int): String? {
            var inumeric: String? = null
            val telephony = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            try {
                val telephonyClass = Class.forName(telephony.javaClass.name)
                val parameter = arrayOfNulls<Class<*>>(1)
                parameter[0] = Int::class.javaPrimitiveType
                val getSimID = telephonyClass.getMethod(predictedMethodName, *parameter)
                val obParameter = arrayOfNulls<Any>(1)
                obParameter[0] = slotID
                val ob_phone = getSimID.invoke(telephony, *obParameter)
                if (ob_phone != null) {
                    inumeric = ob_phone.toString()
                }
            } catch (e: Exception) {
                e.printStackTrace()
                throw GeminiMethodNotFoundException(predictedMethodName)
            }

            return inumeric
        }

        @Throws(CTelephoneInfo.GeminiMethodNotFoundException::class)
        private fun getSIMStateBySlot(context: Context, predictedMethodName: String, slotID: Int): Boolean {

            var isReady = false

            val telephony = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager

            try {

                val telephonyClass = Class.forName(telephony.javaClass.name)

                val parameter = arrayOfNulls<Class<*>>(1)
                parameter[0] = Int::class.javaPrimitiveType
                val getSimStateGemini = telephonyClass.getMethod(predictedMethodName, *parameter)

                val obParameter = arrayOfNulls<Any>(1)
                obParameter[0] = slotID
                val ob_phone = getSimStateGemini.invoke(telephony, *obParameter)

                if (ob_phone != null) {
                    val simState = Integer.parseInt(ob_phone.toString())
                    if (simState == TelephonyManager.SIM_STATE_READY) {
                        isReady = true
                    }
                }
            } catch (e: Exception) {
                e.printStackTrace()
                throw GeminiMethodNotFoundException(predictedMethodName)
            }

            return isReady
        }

        /**
         * 获取设备的唯一设备吗
         */
        fun getPhoneDeviceID(context: Context): String {
            val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
            return tm.deviceId + ""
        }


        @SuppressLint("MissingPermission")
        fun getPhoneUDID(context: Context): String {
            val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager

            var tmDevice = ""
            var tmSerial = ""
            var androidId = ""
            if (tm != null) {
                tmDevice = "" + tm.deviceId
                tmSerial = "" + tm.simSerialNumber
                androidId = "" + android.provider.Settings.Secure.getString(
                        context.contentResolver,
                        android.provider.Settings.Secure.ANDROID_ID)
            }

            val deviceUuid = UUID(androidId.hashCode().toLong(), tmDevice.hashCode().toLong() shl 32 or tmSerial.hashCode().toLong())
            val deviceId = deviceUuid.toString()
            return "KXM-AND" + deviceId
        }
    }

}
